/*
 * Copyright (c) 2017 - 2019, AEye, Inc.
 * All rights reserved.
 */
#ifndef AEYE_ECAST_H_H
#define AEYE_ECAST_H_H

#include <type_traits>

namespace ecast
{
template <typename E>
using UnderlyingType = typename std::underlying_type<E>::type;

template <typename E>
using EnumTypesOnly = typename std::enable_if<std::is_enum<E>::value, E>::type;

}   // namespace ecast

/**
 * @brief Casting Enum value to it's underlying integral type.
 * @tparam E - Enum type
 * @param e  - Value of enum type
 * @return   - Value of underlying integral type.
 */
template <typename E, typename = ecast::EnumTypesOnly<E>>
constexpr inline ecast::UnderlyingType<E> ut_cast(E e) {
  return static_cast<ecast::UnderlyingType<E>>(e);
}

/**
 * @brief Casting integral type to Enum value. Will do cast only if input parameter belongs to the Enum's underlying integral type.
 * @tparam E - Enum type
 * @tparam T - Integral type
 * @param value
 * @return   - Enum's value
 */
template<typename E, typename T>
constexpr inline typename std::enable_if<std::is_enum<E>::value && std::is_integral<T>::value, E>::type toEnum(T value)
{
  return static_cast<E>(value);
}


#endif //AEYE_ECAST_H_H
